//
//  ViewController.swift
//  Automobile
//
//  Created by erkebulan elzhan on 7/19/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit
import SnapKit


// ParametersView <-- cells (Марка, Модель, Параметры)

final class TransportViewController: UIViewController, Alertable {
    
    // MARK: - UI Views
    
    private lazy var postTable: UITableView = {
        let table = UITableView(frame: .zero, style: .grouped)
        table.showsVerticalScrollIndicator = false
        table.tableFooterView = UIView ()
        table.backgroundColor = .whiteBlueColor
        table.delegate = self
        table.dataSource = self
        table.register(PostCell.self, forCellReuseIdentifier: "PostCell")
        table.separatorStyle = .none
        table.addSubview(refreshControl)
        return table
    }()
    
    private lazy var postHeader: UIView = {
        let view = UIView()
        view.backgroundColor = .lightBlueColor
        return view
    }()
    
    private lazy var bannerImage: BannerView = {
        let image = BannerView()
        image.update(image: UIImage(named: "remont_banner"), title: "Ремонт авто", message: "Самая точная диагностика")
        return image
    }()

    fileprivate lazy var searchParameters: ParametersView = {
        let parametersView = ParametersView()
        return parametersView
    }()
    
    private lazy var spinnerView = SpinnerView()
    
    private lazy var refreshControl: RefreshView = {
        let refControl = RefreshView()
        refControl.addTarget(self, action: #selector(updateTable), for: .valueChanged)
        return refControl
    }()
    
    // MARK: - Properties
    
    private lazy var viewModel: TransportViewModel = {
        let vm = TransportViewModel()
        vm.delegate = self
        return vm
    }()
    
    // MARK:- App Life-Cycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        setUpNavBar()
        self.setUpUI()
        self.viewModel.loadPosts()
    }
    
    // MARK: - UI Actions
    
    @objc fileprivate func setCity (sender: UIBarButtonItem) {
        let regionVC = RegionViewController()
        regionVC.delegate = self
        self.navigationController?.pushViewController(regionVC, animated: true)
    }
    
    @objc private func updateTable () {
        self.refreshControl.endRefreshing()
        self.loadPosts()
    }
}


extension TransportViewController: ViewModelProtocol {
    
    func didHappenError(error: RequestError) {
        self.alertError(error: error)
    }
    
    func updatePosts() {
        self.postTable.reloadData()
    }
    
    func updateSpinner(showSpinner: Bool) {
        showSpinner ? spinnerView.startAnimating() : spinnerView.stopAnimating()
    }
    
    func updateCities(cities: [City]?) {
        if cities != nil {
            let txt = cities!.count == 0 ? "Город" : cities!.count == 1 ? cities![0].name : "Несколько"
            self.navigationItem.rightBarButtonItem?.title = txt
        } else {
            self.navigationItem.rightBarButtonItem?.title = "Город"
        }
    }
}


// MARK: - UI Table View Delegate

extension TransportViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let vc = MainViewController()
        vc.setProps(post: viewModel.posts[indexPath.row])
        self.navigationController?.pushViewController(vc, animated: true)
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.posts.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell") as! PostCell
        cell.configure(data: PostModel(post: viewModel.posts[indexPath.row]), index: indexPath.row)
        
        cell.likeButton.tag = indexPath.row
        cell.likeButton.addTarget(self, action: #selector(onLikeClick(sender:)), for: .touchUpInside)
        
        let messageTap = GestureWithTag(target: self, action: #selector(sendMessage(sender:)))
        messageTap.tag = indexPath.row
        cell.messageBtn.addGestureRecognizer(messageTap)
        
        let contactTap = GestureWithTag(target: self, action: #selector(onCall(sender:)))
        contactTap.tag = indexPath.row
        cell.callBtn.addGestureRecognizer(contactTap)
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let _view = UIView()
        _view.addSubview(postHeader)
        postHeader.snp.makeConstraints { (make) in
            make.leading.equalToSuperview()
            make.top.bottom.equalToSuperview()
            make.width.equalToSuperview()
        }
        return _view
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        let offsetY = scrollView.contentOffset.y
        let contentHeight = scrollView.contentSize.height
        if offsetY > contentHeight - scrollView.frame.size.height {
            if viewModel.nextURL != nil {
                self.loadPosts(isPaginated: true)
            }
        }
    }
}


// MARK: - UI Table View Cell Actions

extension TransportViewController: RegionViewControllerDelegate {
    
    func selectCity(city: [City]) {
        viewModel.currentCities = city
    }
    
    @objc private func onLikeClick (sender: UIButton) {
        viewModel.updateFavorite(isRemove: viewModel.posts[sender.tag].isLiked, index: sender.tag)
    }
    
    @objc private func onCall (sender: GestureWithTag) {
        viewModel.callToSeller(index: sender.tag)
    }
    
    @objc private func sendMessage (sender: GestureWithTag) {
        let post = viewModel.posts[sender.tag]
        let commentsVC = CommentsViewController()
        commentsVC.advertID = post.id
        self.navigationController?.pushViewController(commentsVC, animated: true)
    }
}


// MARK: - Network

extension TransportViewController {
    fileprivate func loadPosts (isPaginated: Bool = false) {
        self.viewModel.loadPosts(paginate: isPaginated)
    }
}


// MARK: - Methods

extension TransportViewController {
    
    /// User tapped into parameter
    /// - Parameter item: (placeholder, type, icon, value)
    fileprivate func selectMarkaModel (item: ParametersViewModel) {
        let _region = viewModel.currentCities ?? []
        let carData = CarData(type: .legkovye, vehicleType: nil, currentRegion: _region)
        if (item.type == "markaModel" || item.type == "marka") {
            let vc = MarksViewController()
            vc.setProps(carData: carData)
            self.navigationController?.pushViewController(vc, animated: true)
        }
    }
    
    /// User tapped Параметры button
    fileprivate func openParameters () {
        let filterVC = FilterViewController()
        filterVC.filter = viewModel.filter
        self.navigationController?.pushViewController(filterVC, animated: true)
    }
}


// MARK: - UI

extension TransportViewController {
    
    // MARK: Customizing Navigation Bar
    
    fileprivate func setUpNavBar () {
        
        navigationItem.title = "Транспорт"
        navigationController?.navigationBar.backgroundColor = .white
        navigationController?.navigationBar.prefersLargeTitles = true
        
        let searchController = UISearchController(searchResultsController: nil)
        navigationItem.searchController = searchController
        
        let cityButton = UIBarButtonItem(title: "Город", style: .plain, target: self, action: #selector(setCity(sender:)))
        navigationItem.rightBarButtonItem = cityButton
    }
    
    // MARK: Adding UI elements
    
    fileprivate func setUpUI () {
        self.postHeader.addSubview(bannerImage)
        self.view.addSubview(postTable)
        self.view.addSubview(spinnerView)
        self.postHeader.addSubview(searchParameters)
        searchParameters.layer.cornerRadius = 10.0
        searchParameters.delegate = self
        searchParameters.backgroundColor = .red
        searchParameters.clipsToBounds = true
        searchParameters.items = viewModel.inputs
        self.addConstraints()
    }
    
    fileprivate func addConstraints () {
        
        bannerImage.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(115)
            make.top.equalToSuperview().offset(20)
        }
        searchParameters.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.top.equalTo(bannerImage.snp.bottom).offset(20)
            make.bottom.equalToSuperview().inset(20)
        }
        postTable.snp.makeConstraints { (make) in
            make.top.equalTo(view.safeAreaLayoutGuide)
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
        }
        spinnerView.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
    }
}

// MARK: Марка, Модель, Параметры View

extension TransportViewController: ParametersViewDelegate {
    
    func didClearValue(value: String?, placeholder: String, itemIndex: Int) {}
    
    func didSelectParameter(item: ParametersViewModel) {
        if item.type == "parameters" {
            self.openParameters()
        } else {
            self.selectMarkaModel(item: item)
        }
    }
}
